
#ifndef _MEMBER_BSCENE_H_
#define _MEMBER_BSCENE_H_

#include <BMap>
#include <BEvent>
#include <BScene>
#include <BOctTree>

#define scene_member(scene)		((member_BScene*)((BScene*)scene)->_ptr)

namespace BWE
{
	struct SceneSet
	{
		BArray<BShapeHolder>	shapes;
		BArray<BNodeHolder>		nodes;
		BArray<BLight*>			lights;
		BArray<BCamera*>		cameras;
	};
	typedef BOctTree<SceneSet>				SceneOctTree;
	typedef SceneOctTree::Item				SceneOctTreeItem;
	typedef SceneOctTree::ItemArray			SceneOctTreeItemArray;
	typedef SceneOctTree::ConstItemArray	ConstSceneOctTreeItemArray;

	class member_BScene : public BObject
	{
		friend class BScene;
	public:
		member_BScene(BScene* scene);
		~member_BScene();

		void update(BReal time);
		void updateGroup(BGroup* group, BReal time);

		void freshOctTree();
		void freshGroupOctTree(BGroup* group);

		void collectShapes(SceneOctTreeItem& item, BShapeArray& shapes);
		void collectNodes(SceneOctTreeItem& item, BNodeArray& nodes);
		void collectLights(SceneOctTreeItem& item, BLightArray& lights);
		void collectCameras(SceneOctTreeItem& item, BCameraArray& cameras);

		void slotShapeEnabled(BObject* object);
		void slotShapeFresh(BObject* object);
		void slotShapeDirty(BObject* object);
		void slotShapeTransformed(BObject* object);

		void slotNodeEnabled(BObject* object);
		void slotNodeFresh(BObject* object);
		void slotNodeDirty(BObject* object);
		void slotNodeInsert(BObject* object, const BValue& value);
		void slotNodeRemove(BObject* object, const BValue& value);
		void slotNodeTransformed(BObject* object);

		void slotGroupEnabled(BObject* object);
		void slotGroupFresh(BObject* object);
		void slotGroupDirty(BObject* object);
		void slotGroupInsert(BObject* object, const BValue& value);
		void slotGroupRemove(BObject* object, const BValue& value);

		BScene*					boss;
		bool					refresh;
		bool					dirtySpace;
		BSpace					space;
		BSet<BShapeHolder>		shapes;
		BSet<BNodeHolder>		nodes;
		BSet<BLight*>			lights;
		BSet<BCamera*>			cameras;
		BSet<BGroupHolder>		groups;
		BSet<BConstraintHolder>	constraints;

		BHolder<SceneOctTree>	sceneOctTree;
		BMap<const BShape*, SceneOctTreeItem> shapeSpaceMap;
		BMap<const BNode*, SceneOctTreeItem> nodeSpaceMap;
	};
}
#endif
